//
// Copyright (c) 2009-2011, chunquedong
//
// This file is part of ChunMap project
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
//
// History:
//   2011-09-04  Jed Young  Creation
//

using gfx2
using gfx2Imp
using chunmapModel
using chunmapData
using concurrent

**
** Googlemap datasource
**
@Js
@Serializable { simple = true }
const class GDataSource : RasterDataSource
{
  ** global envelope
  override const Envelope envelope := Envelope(-Mercator.maxDis,
    -Mercator.maxDis, Mercator.maxDis, Mercator.maxDis)

  private const ImageCache cache
  const Uri rootUri
  private const ActorPool pool := ActorPool()

  private const |->|? onLoaded

  new make(Uri rootUri := `http://mt2.google.cn/vt/v=w2.116&hl=zh-CN&gl=cn`, |->|? onLoaded := null)
  {
    this.cache = ImageCache.create
    this.rootUri = rootUri
    this.onLoaded = onLoaded
  }

  override Str toStr() { rootUri.toStr }
  static GDataSource fromStr(Str s)
  {
    uri := s.toUri
    |->|? onLoaded := Actor.locals["chunmapTaster.TileDataSource.callback"]
    return GDataSource(uri, onLoaded)
  }

  ** get the tile envelope
  internal Envelope getEnvelope(Tile tile) { GEncode.getEnvelope(tile) }

  internal Image2? getImage(GTile tile_)
  {
    tile := tile_.proxy ?: tile_

    name := tile.toStr
    image := cache.get(name)
    if (image != null) return image
    if (cache.contains(name)) return null

    cache.set(name, null)
    uri := getUri(tile.x, tile.y, tile.z)

    Gfx2.setEngine("SWT")
    image = Image2.fromUri(uri)
    {
      cache.set(name, it)
      if(onLoaded != null) onLoaded()
    }
    return null
  }

  override Void each(Condition condition, |Feature| f)
  {
    getTileSet(condition.envelope, condition.scale).each(f)
  }

  private GTile[] getTileSet(Envelope envelope, Float scale)
  {
    list := GEncode.getTileSet(envelope, scale)
    list.each
    {
      it.setDataSource(this)
    }
    return list
  }

  private Uri getUri(Int x, Int y, Int z)
  {
    "${rootUri}&x=${x}&y=${y}&z=${z}&s=G".toUri
  }
}